package com.ruoyi.net.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.net.domain.*;
import com.ruoyi.net.mapper.NetElementLinkMapper;
import com.ruoyi.net.mapper.NetElementMapper;
import com.ruoyi.net.netconf.util.NetconfUtils;
import com.ruoyi.net.service.INetElementService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.net.mapper.NetGroupMapper;
import com.ruoyi.net.service.INetGroupService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 网元逻辑域Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-10-27
 */
@Service
public class NetGroupServiceImpl implements INetGroupService 
{
    @Autowired
    private NetGroupMapper netGroupMapper;

    @Autowired
    private INetElementService netElementService;

    @Autowired
    private NetElementLinkMapper netElementLinkMapper;

    /**
     * 查询网元逻辑域
     * 
     * @param id 网元逻辑域主键
     * @return 网元逻辑域
     */
    @Override
    public NetGroup selectNetGroupById(String id)
    {
        return netGroupMapper.selectNetGroupById(id);
    }

    /**
     * 查询网元逻辑域列表
     * 
     * @param netGroup 网元逻辑域
     * @return 网元逻辑域
     */
    @Override
    public List<NetGroup> selectNetGroupList(NetGroup netGroup)
    {
        return netGroupMapper.selectNetGroupList(netGroup);
    }

    /**
     * 新增网元逻辑域
     * 
     * @param netGroup 网元逻辑域
     * @return 结果
     */
    @Override
//    @Transactional
    public int insertNetGroup(NetGroup netGroup)
    {
        String uuid = IdUtils.simpleUUID();
        if (StringUtils.isEmpty(netGroup.getId())) {
            netGroup.setId(uuid);
        }
        if (StringUtils.isEmpty(netGroup.getParentId())) {
            netGroup.setParentId(uuid);
        }
        netGroup.setCreateBy(SecurityUtils.getUsername());
        netGroup.setCreateTime(DateUtils.getNowDate());
        int result = netGroupMapper.insertNetGroup(netGroup);
        /*// 网元设备
        if ("2".equals(netGroup.getGroupType())) {
            NetElement netElement = new NetElement();
            netElement.setId(uuid);
            netElement.setElementName(netGroup.getGroupName());
            netElement.setCreateTime(netGroup.getCreateTime());
            result = netElementMapper.insertNetElement(netElement);
        }*/
        return result;
    }

    /**
     * 修改网元逻辑域
     * 
     * @param netGroup 网元逻辑域
     * @return 结果
     */
    @Override
    public int updateNetGroup(NetGroup netGroup)
    {
//        netGroup.setUpdateBy(SecurityUtils.getUsername());
        netGroup.setUpdateTime(DateUtils.getNowDate());
        return netGroupMapper.updateNetGroup(netGroup);
    }

    /**
     * 批量删除网元逻辑域
     * 
     * @param ids 需要删除的网元逻辑域主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteNetGroupByIds(String[] ids)
    {
        // 删除网元设备
        netElementService.deleteNetElementByIds(ids);
        return netGroupMapper.deleteNetGroupByIds(ids);
    }

    /**
     * 删除网元逻辑域信息
     * 
     * @param id 网元逻辑域主键
     * @return 结果
     */
    @Override
    public int deleteNetGroupById(String id)
    {
        return netGroupMapper.deleteNetGroupById(id);
    }

    @Override
    public List<GroupTreeSelect> selectGroupTreeList(NetGroup netGroup) {
        List<NetGroup> groups = netGroupMapper.selectGroupTreeList(netGroup);
        return buildGroupTreeSelect(groups);
    }

    @Override
    public List<TopoVo> selectTopo(String id) {
        List<TopoVo> result = new ArrayList<>();

        /*
        // TODO: 2024/11/8 判断id是逻辑域还是网元
        NetGroup currentGroup = netGroupMapper.selectNetGroupById(id);
        if ("2".equals(currentGroup.getGroupType())) {
            id = currentGroup.getParentId();
        }
        */

        // 2024/11/5 查找下一级节点
        NetGroup netGroup = new NetGroup();
        netGroup.setParentId(id);
        List<NetGroup> nodes = netGroupMapper.selectNetGroupList(netGroup);
        if (nodes.isEmpty()) {
            return result;
        }
        List<TopoVo> topoVos = new ArrayList<>();
        /*// 获取id列
        List<String> ids = nodes.stream()
                .map(NetGroup::getId)
                .collect(Collectors.toList());
        for (int i = 0; i < ids.size(); i++) {
            for (int j = 0; j < ids.size(); j++) {
                if (i != j) {
                    TopoVo topoVo = new TopoVo();
                    topoVo.setFromId(ids.get(i));
                    topoVo.setToId(ids.get(j));
//                    System.out.println(elements[i] + elements[j]);
                    topoVos.add(topoVo);
                }
            }
        }*/
        for (int i = 0; i < nodes.size(); i++) {
            for (int j = 0; j < nodes.size(); j++) {
                if (i != j) {
                    TopoVo topoVo = new TopoVo();
                    topoVo.setFromId(nodes.get(i).getId());
                    topoVo.setFromName(nodes.get(i).getGroupName());
                    topoVo.setToId(nodes.get(j).getId());
                    topoVo.setToName(nodes.get(j).getGroupName());
//                    System.out.println(elements[i] + elements[j]);
                    topoVos.add(topoVo);
                }
            }
        }

        // 获取当前节点有关的网元连线
        NetElementLink netElementLink = new NetElementLink();
        netElementLink.setStartGroupId(id);
        netElementLink.setEndGroupId(id);
        List<NetElementLinkVo> relationLinks = netElementLinkMapper.selectNetElementLinkVoList(netElementLink);

        List<TopoVo> nonTopoVos = new ArrayList<>();
        if (relationLinks.isEmpty()) {
            return result;
        }
        for (TopoVo item : topoVos) {
            List<NetElementLinkVo> tempLinks = relationLinks.stream().filter(relationLink ->
                    relationLink.getStartGroupId().contains(item.getFromId())
                    && relationLink.getEndGroupId().contains(item.getToId()))
                    .collect(Collectors.toList());
//            item.setLinkData(relationLinks.stream().filter(relationLink -> relationLink.getStartGroupId().contains(item.getFromId()) && relationLink.getEndGroupId().contains(item.getToId())).collect(Collectors.toList()));
            // 获取空数据
            if (tempLinks.isEmpty()) {
                nonTopoVos.add(item);
            }
            else {
                for (NetElementLinkVo link : tempLinks) {
                    TopoVo topoVo = new TopoVo();
                    BeanUtils.copyProperties(item, topoVo);
                    List<NetElementLinkVo> tempLinkDatas = new ArrayList<>();
                    tempLinkDatas.add(link);
                    topoVo.setLinkData(tempLinkDatas);
                    result.add(topoVo);
                }
            }

        }
        // 清空 linkData 为空的数据
//        topoVos.removeAll(nonTopoVos);
        result.removeAll(nonTopoVos);
//        return topoVos;
        return result;
    }

    private List<GroupTreeSelect> buildGroupTreeSelect(List<NetGroup> groups) {
        List<NetGroup> groupTress = buildGroupTree(groups);
        return groupTress.stream().map(GroupTreeSelect::new).collect(Collectors.toList());
    }

    private List<NetGroup> buildGroupTree(List<NetGroup> groups) {
        List<NetGroup> returnList = new ArrayList<>();
        List<String> tempList = groups.stream().map(NetGroup::getId).collect(Collectors.toList());
        for (NetGroup group : groups) {
            if (!tempList.contains(group.getParentId())) {
                recursionFn(groups, group);
                returnList.add(group);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = groups;
        }
        return returnList;
    }

    private void recursionFn(List<NetGroup> groups, NetGroup group) {
        List<NetGroup> childList = getChildList(groups, group);
        group.setChildren(childList);
        for(NetGroup child : childList) {
            if(hasChild(groups, child)) {
                recursionFn(groups, child);
            }
        }
    }


    private List<NetGroup> getChildList(List<NetGroup> groups, NetGroup group) {
        List<NetGroup> childList = new ArrayList<>();
        Iterator<NetGroup> iterator = groups.iterator();
        while(iterator.hasNext()) {
            NetGroup next = iterator.next();
            if(group.getId().equals(next.getParentId())) {
                childList.add(next);
            }
        }
        return childList;
    }

    private boolean hasChild(List<NetGroup> groups, NetGroup child) {
        return getChildList(groups, child).size() > 0;
    }


    @Override
    public int batchUpdate(List<NetGroup> netGroups) {
        return netGroupMapper.batchUpdate(netGroups);
    }
}
